home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
dev
/
c
/
vbccppcsrc.lha
/
vbcc
/
ar
/
ar.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-07
|
6KB
|
263 lines
/* $VER: ar ar.c V0.1 (31.01.98)
*
* This file is part of ar, a portable archive maintanance
* utility for normal and BSD-style archives.
* Copyright (c) 1999 Frank Wille
*
* ar is freeware and part of the portable and retargetable ANSI C
* compiler vbcc, copyright (c) 1995-99 by Volker Barthelmann.
* ar may be freely redistributed as long as no modifications are
* made and nothing is charged for it. Non-commercial usage is allowed
* without any restrictions.
* EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
* SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
*
*
* v0.1 (31.01.99) phx
* First working version, which only supports 'q' (quick append)
* and 't' (table of contents), reads and writes normals and
* BSD-style archives. Symbol table will not be created!
* v0.0 (29.01.99) phx
* File created.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ar.h"
#include "errors.h"
extern void show_usage(void);
extern void ar_delete(struct Args *);
extern void ar_move(struct Args *);
extern void ar_print(struct Args *);
extern void ar_qappend(struct Args *);
extern void ar_replace(struct Args *);
extern void ar_contents(struct Args *);
extern void ar_extract(struct Args *);
/* local */
static uint32 getmodifiers(char,char *,uint32);
static uint32 chkmodifier(uint32,uint32,char,char);
static void argerror(void);
#ifdef AMIGA
extern char **expand_args(int *,int,char *[],int);
int main(int _argc,char *_argv[])
{
int argc;
char **argv = expand_args(&argc,_argc,_argv,2);
#else
int main(int argc,char *argv[])
{
#endif
struct Args a;
char *p,c;
/* init */
memset(&a,0,sizeof(struct Args));
/* parse arguments */
if (argc < 3) {
if (argc == 2)
error(EMISSARCHNAME);
argerror();
}
p = argv[1];
if (*p == '-')
p++;
/* get key argument */
switch (c = *p++) {
case 'd': /* delete */
if (argc < 4)
error(EMISSFILENAME);
a.modifier = getmodifiers(c,p,AR_TRUNC|AR_BSD|AR_VERBOSE);
a.arname = argv[2];
a.files = &argv[3];
a.filecnt = argc - 3;
ar_delete(&a);
break;
case 'm': /* move */
a.modifier = getmodifiers(c,p,AR_TRUNC|AR_BSD|AR_VERBOSE|AR_POS);
if (a.modifier & AR_POS) {
if (argc < 4)
error(EMISSARCHNAME);
if (argc < 5)
error(EMISSFILENAME);
a.position = argv[2];
a.arname = argv[3];
a.files = &argv[4];
a.filecnt = argc - 4;
}
else {
if (argc < 4)
error(EMISSFILENAME);
a.arname = argv[2];
a.files = &argv[3];
a.filecnt = argc - 3;
}
ar_move(&a);
break;
case 'p': /* print */
a.modifier = getmodifiers(c,p,AR_TRUNC|AR_VERBOSE);
a.arname = argv[2];
if (argc >= 4) {
a.files = &argv[3];
a.filecnt = argc - 3;
}
ar_print(&a);
break;
case 'q': /* quick append */
if (argc < 4)
error(EMISSFILENAME);
a.modifier = getmodifiers(c,p,AR_TRUNC|AR_BSD|AR_VERBOSE|AR_CREATIGN);
a.arname = argv[2];
a.files = &argv[3];
a.filecnt = argc - 3;
ar_qappend(&a);
break;
case 'r': /* replace */
a.modifier = getmodifiers(c,p,AR_TRUNC|AR_BSD|AR_VERBOSE|
AR_POS|AR_CREATIGN|AR_UPDATE);
if (a.modifier & AR_POS) {
if (argc < 4)
error(EMISSARCHNAME);
if (argc < 5)
error(EMISSFILENAME);
a.position = argv[2];
a.arname = argv[3];
a.files = &argv[4];
a.filecnt = argc - 4;
}
else {
if (argc < 4)
error(EMISSFILENAME);
a.arname = argv[2];
a.files = &argv[3];
a.filecnt = argc - 3;
}
ar_replace(&a);
break;
case 't': /* table of contents */
a.modifier = getmodifiers(c,p,AR_TRUNC|AR_VERBOSE);
a.arname = argv[2];
if (argc >= 4) {
a.files = &argv[3];
a.filecnt = argc - 3;
}
ar_contents(&a);
break;
case 'x': /* extract */
a.modifier = getmodifiers(c,p,AR_TRUNC|AR_VERBOSE|AR_PRESERVE|
AR_UPDATE);
a.arname = argv[2];
if (argc >= 4) {
a.files = &argv[3];
a.filecnt = argc - 3;
}
ar_extract(&a);
break;
default:
error(EUNKNOWNKEY,c);
break;
}
return (0);
}
void cleanup()
{
}
static uint32 getmodifiers(char key,char *s,uint32 allowed)
{
char c;
uint32 m = 0;
for (;;) {
switch (c = *s++) {
case '\0':
break;
case 'a':
m |= chkmodifier(AR_AFTER,allowed,c,key);
continue;
case 'b':
m |= chkmodifier(AR_BEFORE,allowed,c,key);
continue;
case 'i':
m |= chkmodifier(AR_BEFORE,allowed,c,key);
continue;
case 'c':
m |= chkmodifier(AR_CREATIGN,allowed,c,key);
continue;
case 'o':
m |= chkmodifier(AR_PRESERVE,allowed,c,key);
continue;
case 'u':
m |= chkmodifier(AR_UPDATE,allowed,c,key);
continue;
case 'v':
m |= chkmodifier(AR_VERBOSE,allowed,c,key);
continue;
case 'T':
m |= chkmodifier(AR_TRUNC,allowed,c,key);
continue;
case 'B':
m |= chkmodifier(AR_BSD,allowed,c,key);
continue;
default:
error(EMODNOTALLOWED,c,key);
continue;
}
break;
}
return (m);
}
static uint32 chkmodifier(uint32 mod,uint32 allowed,char c,char key)
{
if (mod & allowed)
return (mod);
error(EMODNOTALLOWED,c,key);
return (0);
}
static void argerror(void)
{
show_usage();
exit(1);
}
size_t filesize(FILE *fh,char *name)
{
long oldpos,size;
if ((oldpos = ftell(fh)) >= 0)
if (fseek(fh,0,SEEK_END) >= 0)
if ((size = ftell(fh)) >= 0)
if (fseek(fh,oldpos,SEEK_SET) >= 0)
return ((size_t)size);
fclose(fh);
error(EREADERR,name); /* doesn't return */
return (0);
}